package code;

import java.io.*;
import java.math.BigInteger;
import java.security.*;
import java.security.cert.*;
import java.security.cert.Certificate;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Vector;

import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.sound.midi.SysexMessage;

import org.bouncycastle.jce.X509Principal;
import org.bouncycastle.openssl.PEMReader;
import org.bouncycastle.openssl.PEMWriter;
import org.bouncycastle.util.encoders.Base64;
import org.bouncycastle.x509.X509V1CertificateGenerator;
 
public class KeyStoreManager {

	private static final String KEYSTORE_TYPE = "JCEKS";
	private static final String BEGIN_CERT     = "-----BEGIN CERTIFICATE-----";
    private static final String END_CERT       = "-----END CERTIFICATE-----";

	
    private String KEYSTORE_FILE;
    private String KEYSTORE_PASSWORD;
    private KeyStore keyStore = null;
    
    public KeyStore getKeyStore() {
		return keyStore;
	}

	public KeyStoreManager(String keyStoreFile, String keyStorePassword) {
    	Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    	
        KEYSTORE_FILE = keyStoreFile;
        KEYSTORE_PASSWORD = keyStorePassword;
        
        this.keyStore = openKeyStore();
    }
    
    private KeyStore openKeyStore() {
        KeyStore keyStore = null;
		try {
			keyStore = KeyStore.getInstance(KEYSTORE_TYPE);
			
			InputStream stream;
			try {
				stream = new FileInputStream(KEYSTORE_FILE);
			} catch (FileNotFoundException e) {
				System.err.println("Can not open Keystore file");
				e.printStackTrace(System.err);
				System.err.println();
				return null;
			}			
			keyStore.load(stream, KEYSTORE_PASSWORD.toCharArray());
			
		} catch (KeyStoreException e) {
			System.err.println("Can not get Keystore instance, possibly wrong Keystore type");
			e.printStackTrace(System.err);
			System.err.println();
		} catch (NoSuchAlgorithmException e) {
			System.err.println("Can not load Keystore.");
			e.printStackTrace(System.err);
			System.err.println();
		} catch (CertificateException e) {
			System.err.println("Can not load Keystore.");
			e.printStackTrace(System.err);
			System.err.println();
		} catch (IOException e) {
			System.err.println("Can not load Keystore.");
			e.printStackTrace(System.err);
			System.err.println();
		}
        return keyStore;
    }
    
    public void createKeyStore(String fileName, String password) {
    	
    	// Create an empty keystore
		try {
			this.keyStore = KeyStore.getInstance(KEYSTORE_TYPE);
			this.keyStore.load(null, password.toCharArray());
		} catch (KeyStoreException e) {
			System.err.println("Can not create Keystore, possibly wrong Keystore type");
			e.printStackTrace(System.err);
			System.err.println();
		} catch (NoSuchAlgorithmException e) {
			System.err.println("Can not create Keystore.");
			e.printStackTrace(System.err);
			System.err.println();
		} catch (CertificateException e) {
			System.err.println("Can not create Keystore.");
			e.printStackTrace(System.err);
			System.err.println();
		} catch (IOException e) {
			System.err.println("Can not create Keystore.");
			e.printStackTrace(System.err);
			System.err.println();
		}
		
		// Save the empty keystore to the file
		this.KEYSTORE_FILE = fileName;
		this.KEYSTORE_PASSWORD = password;
        this.saveKeyStore();
        
        // Get the saved keystore back
    	this.keyStore = this.openKeyStore();
    }
    
    public void saveKeyStore() {
    	// Save in-memory keystore to the file
    	FileOutputStream fos;
		try {
			fos = new FileOutputStream(KEYSTORE_FILE);
			try {
				this.keyStore.store(fos, KEYSTORE_PASSWORD.toCharArray());
				fos.close();
			} catch (KeyStoreException e) {
				System.err.println("Can not save Keystore.");
				e.printStackTrace(System.err);
				System.err.println();
			} catch (NoSuchAlgorithmException e) {
				System.err.println("Can not save Keystore.");
				e.printStackTrace(System.err);
				System.err.println();
			} catch (CertificateException e) {
				System.err.println("Can not save Keystore.");
				e.printStackTrace(System.err);
				System.err.println();
			} catch (IOException e) {
				System.err.println("Can not save Keystore.");
				e.printStackTrace(System.err);
				System.err.println();
			}
		} catch (FileNotFoundException e) {
			System.err.println("Can not open Keystore file.");
			e.printStackTrace(System.err);
			System.err.println();
		}
    }
    
    public KeyPair createKeyPair(String keyAlgorithm, int keySize) {
        KeyPairGenerator keyGen;
        KeyPair keyPair = null;
        
		try {
			keyGen = KeyPairGenerator.getInstance(keyAlgorithm, "BC");
			keyGen.initialize(keySize, new SecureRandom());
	        keyPair = keyGen.generateKeyPair();
		} catch (NoSuchAlgorithmException e) {
			System.err.println("Can not create Keypair.");
			e.printStackTrace(System.err);
		} catch (NoSuchProviderException e) {
			System.err.println("Can not create Keypair.");
			e.printStackTrace(System.err);
		}
        return keyPair;
    }
    
    private SecretKey createSecretKey(String algorithm, Integer size) {
    	
    	SecretKey key = null;    	
    	KeyGenerator keyGen;
		try {
			keyGen = KeyGenerator.getInstance(algorithm);
			keyGen.init(size);
			key = keyGen.generateKey();
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return key;
    }
    
    public HashSet<String> listAllKeys() {
    	HashSet<String> keys = new HashSet<String>();
    	
    	try {
			Enumeration<String> en = this.keyStore.aliases();
			while (en.hasMoreElements()) { 
				String alias = (String)en.nextElement();
				// Does alias refer to a private key?
				if (this.keyStore.isKeyEntry(alias)) {
					keys.add(alias);
				}
			}
		} catch (KeyStoreException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	return keys;
    }

    public HashSet<String> listAllCerts() {
    	HashSet<String> certs = new HashSet<String>();
    	
    	try {
			Enumeration<String> en = this.keyStore.aliases();
			while (en.hasMoreElements()) { 
				String alias = (String)en.nextElement();
				// Does alias refer to a private key?
				if (this.keyStore.isCertificateEntry(alias)) {
					certs.add(alias);
				}
			}
		} catch (KeyStoreException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	return certs;
    }
    
    private X509Certificate[] generateCertificateChain(PublicKey publicKey, PrivateKey privKey, 
    		BigInteger serialNumber, String issuerDN, Date notBefore, Date notAfter,
    		String subjectDN, String signatureAlgorithm) {
    	
    	X509V1CertificateGenerator certGen = new X509V1CertificateGenerator();
        certGen.setSerialNumber(serialNumber);
        certGen.setIssuerDN(new X509Principal(issuerDN));
        certGen.setNotBefore(notBefore);
        certGen.setNotAfter(notAfter);
        certGen.setSubjectDN(new X509Principal(subjectDN));
        certGen.setPublicKey(publicKey);
        certGen.setSignatureAlgorithm(signatureAlgorithm);
       
        X509Certificate[] chain = new X509Certificate[1];
        
		try {
			chain[0]= certGen.generateX509Certificate(privKey, "BC");
		} catch (InvalidKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchProviderException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SignatureException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
        return chain;
    	
    }
 
    public void saveKeyPair(String keyAlias, KeyPair keyPair, String keyPassword) {
    	PublicKey publicKey = keyPair.getPublic();
    	PrivateKey privKey = keyPair.getPrivate();
    	
      X509Certificate[] chain = this.generateCertificateChain(publicKey, privKey, 
		BigInteger.valueOf(1), "CN=" + keyAlias + ",OU=Public Key Certificate, O=Atoco, L=Local, ST=, C=TR", 
		new Date( System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30), 
		new Date( System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30), 
		"CN=" + keyAlias + ",OU=Public Key Certificate, O=Atoco, L=Local, ST=, C=TR", "MD5WithRSAEncryption");
      
      try {
    	  this.keyStore.setKeyEntry(keyAlias, privKey, keyPassword.toCharArray(), chain);
      } catch (KeyStoreException e) {
    	  // TODO Auto-generated catch block
    	  e.printStackTrace();
      }
    }
    
    public void saveKeyPair(String keyAlias, KeyPair keyPair, String keyPassword,
    		BigInteger serialNumber, String issuerDN, Date notBefore, Date notAfter,
    		String subjectDN, String signatureAlgorithm) {
    	
    	PublicKey publicKey = keyPair.getPublic();
    	PrivateKey privKey = keyPair.getPrivate();
    	
      X509Certificate[] chain = this.generateCertificateChain(publicKey, privKey, 
		serialNumber, issuerDN, notBefore, notAfter, subjectDN, signatureAlgorithm);
      
      try {
    	  this.keyStore.setKeyEntry(keyAlias, privKey, keyPassword.toCharArray(), chain);
      } catch (KeyStoreException e) {
    	  // TODO Auto-generated catch block
    	  e.printStackTrace();
      }
    }
    
    public X509Certificate generateCertificate(PublicKey publicKey, PrivateKey privKey, 
    		BigInteger serialNumber, String issuerDN, Date notBefore, Date notAfter,
    		String subjectDN, String signatureAlgorithm) {
    	
    	X509Certificate cert = null;
    	
    	X509V1CertificateGenerator certGen = new X509V1CertificateGenerator();
        certGen.setSerialNumber(serialNumber);
        certGen.setIssuerDN(new X509Principal(issuerDN));
        certGen.setNotBefore(notBefore);
        certGen.setNotAfter(notAfter);
        certGen.setSubjectDN(new X509Principal(subjectDN));
        certGen.setPublicKey(publicKey);
        certGen.setSignatureAlgorithm(signatureAlgorithm);
       
		try {
			cert = certGen.generateX509Certificate(privKey, "BC");
		} catch (InvalidKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchProviderException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SignatureException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
        return cert;
    }
    
    public void saveCertificate(String certAlias, X509Certificate cert) {
    	try {
			this.keyStore.setCertificateEntry(certAlias, cert);
		} catch (KeyStoreException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
    
    // Returns PrivateKey for a given alias
    public Key getPrivateKey(String keyAlias, String keyPassword) {
    	Key privKey = null;
    	try {
			privKey = this.keyStore.getKey(keyAlias, keyPassword.toCharArray());
		} catch (UnrecoverableKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (KeyStoreException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return privKey;
    }
    
    public Key getPublicKey(String keyAlias) {
    	Key pubKey = null;
    	try {
			pubKey = this.keyStore.getCertificate(keyAlias).getPublicKey();
		} catch (KeyStoreException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (java.lang.NullPointerException e) {
			// No public key for given alias
			// This means alias is of type SecretKey (Symmetric Key)
		}
		return pubKey;
    }
    
    public Certificate getCertificate(String certAlias) {
    	Certificate cert = null;
    	try {
			cert = this.keyStore.getCertificate(certAlias);
		} catch (KeyStoreException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return cert;
    }
    
    public boolean hasCaCertificate() {
//    	if(ksm.getKeyStore().containsAlias("caCert")==false || 
//    			ksm.getKeyStore().isCertificateEntry("caCert")==false)
    	try {
			if(this.keyStore.containsAlias("cert-caCert") && this.keyStore.isCertificateEntry("cert-caCert")) {
				return true;
			}
		} catch (KeyStoreException e) {
			e.printStackTrace();
		}
		return false;
    }
    
    public void saveSecretKey(String keyAlias, SecretKey secretKey, String keyPassword) {
    	try {
    		this.keyStore.setKeyEntry(keyAlias, secretKey, keyPassword.toCharArray(), null);
    	} catch (KeyStoreException e) {
    		// TODO Auto-generated catch block
    		e.printStackTrace();
    	}
    }
    
    public SecretKey getSecretKey(String keyAlias, String keyPassword) {
    	SecretKey secretKey = null;
    	try {
			secretKey = (SecretKey)this.keyStore.getKey(keyAlias, keyPassword.toCharArray());
		} catch (UnrecoverableKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (KeyStoreException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return secretKey;
    }
    
    // Return Certificate Base 64 Encoded (PEM format)
    private String getCertBase64Encoded(Certificate cert) {
    	try {
	        String sTmp = new String(Base64.encode(cert.getEncoded()));
	        String sEncoded = BEGIN_CERT + "\r\n";
	        for(int iCnt = 0; iCnt < sTmp.length(); iCnt += 64)
	        {
	            int iLineLength;
	            if(iCnt + 64 > sTmp.length())
	                iLineLength = sTmp.length() - iCnt;
	            else
	                iLineLength = 64;
	            sEncoded = sEncoded + sTmp.substring(iCnt, iCnt + iLineLength) + "\r\n";
	        }
	
	        sEncoded = sEncoded + END_CERT + "\r\n";
	        return sEncoded;
	    } catch(CertificateException e) {
			e.printStackTrace(System.err);
	    }
	    return null;
    }

    // Save a X509 Certificate to a file, in Base64 format (PEM Format)
    public void saveCerttoFilePem(String filename, String certAlias) {
    	Certificate cert = getCertificate(certAlias);
	    	if(cert != null) {
	    	FileWriter output;
			try {
				output = new FileWriter(filename, false);
		        output.write(getCertBase64Encoded(cert));
		        output.flush();
		        output.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
    	}
    }
    
    public void saveCerttoFileDer(String fileName, String certAlias) {
    	Certificate cert = getCertificate(certAlias);
    	if(cert != null) {
    		try {
				byte[] encodedCert = cert.getEncoded();
				FileOutputStream certfos = new FileOutputStream(fileName);
			    certfos.write(encodedCert);
			    certfos.close();
			} catch (CertificateEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    		
    	}
    }
    
    public void saveCerttoFileDer(String fileName, Certificate cert) {
    	if(cert != null) {
    		try {
				byte[] encodedCert = cert.getEncoded();
				FileOutputStream certfos = new FileOutputStream(fileName);
			    certfos.write(encodedCert);
			    certfos.close();
			} catch (CertificateEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    	}
    }
    
    public Certificate loadCertfromFileDer(String fileName) {
    	Certificate cert = null;
		try {
			FileInputStream certfis = new FileInputStream(fileName);
			java.security.cert.CertificateFactory cf =
	    		java.security.cert.CertificateFactory.getInstance("X.509");
	    	cert = cf.generateCertificate(certfis);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (CertificateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return cert;
    }
    
    // Save private key to a file, in Base64 format (PEM Format)
    private void saveKeytoFile(String fileName, Key key) {
    	FileWriter output;
		try {
			output = new FileWriter(fileName, false);
			PEMWriter writer = new PEMWriter(output, "BC");
			writer.writeObject(key);
			output.flush();
			writer.close();
			output.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	
    }
    
    private void loadKeyPairfromFile(String keyFileName, String certFileName, String keyAlias, String keyPassword) {
    	FileReader re1;
    	FileReader re2;
    	X509Certificate[] chain = new X509Certificate[1];
		try {
			re1 = new FileReader(keyFileName);
			re2 = new FileReader(certFileName);
			PEMReader keyFile = new PEMReader(re1);
			PEMReader certFile = new PEMReader(re2);
			KeyPair kp = (KeyPair) keyFile.readObject();
			chain[0] = (X509Certificate) certFile.readObject();
			keyFile.close();
			certFile.close();
	    	this.keyStore.setKeyEntry(keyAlias, kp.getPrivate(), keyPassword.toCharArray(), chain);
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (KeyStoreException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	
    }
    
    public void deleteKeyPair(String keyAlias) {
    	try {
    		if (this.keyStore.isKeyEntry(keyAlias)) {
    			this.keyStore.deleteEntry(keyAlias);
    		}
		} catch (KeyStoreException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
    
    public void deleteCert(String certAlias) {
    	try {
    		if (this.keyStore.isCertificateEntry(certAlias)) {
    			this.keyStore.deleteEntry(certAlias);
    		}
		} catch (KeyStoreException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
    
    public void signFile(PrivateKey privateKey, PublicKey publicKey, String inDataFileName, 
    		String outSignatureFileName, String outPublicKeyFileName) {
    	try {
    		//Get signature object ready
			Signature dsa = Signature.getInstance("SHA1withRSA", "BC");
			dsa.initSign(privateKey);
			//Get the file into buffer
			FileInputStream fis = new FileInputStream(inDataFileName);
			BufferedInputStream bufin = new BufferedInputStream(fis);
			byte[] buffer = new byte[1024];
			int len;
			while ((len = bufin.read(buffer)) >= 0) {
			    dsa.update(buffer, 0, len);
			};
			bufin.close();
			//Generate digital signature
			byte[] realSig = dsa.sign();
			// save the signature in a file
	        FileOutputStream sigfos = new FileOutputStream(outSignatureFileName);
	        sigfos.write(realSig);
	        sigfos.close();
	        // save the public key in a file
	        byte[] key = publicKey.getEncoded();
	        FileOutputStream keyfos = new FileOutputStream(outPublicKeyFileName);
	        keyfos.write(key);
	        keyfos.close();

		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchProviderException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SignatureException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
    
    public void signFile(PrivateKey privateKey, Certificate cert, String inDataFileName, 
    		String outSignatureFileName, String outCertFileName) {
    	try {
    		//Get signature object ready
			Signature dsa = Signature.getInstance("SHA1withRSA", "BC");
			dsa.initSign(privateKey);
			//Get the file into buffer
			FileInputStream fis = new FileInputStream(inDataFileName);
			BufferedInputStream bufin = new BufferedInputStream(fis);
			byte[] buffer = new byte[1024];
			int len;
			while ((len = bufin.read(buffer)) >= 0) {
			    dsa.update(buffer, 0, len);
			};
			bufin.close();
			//Generate digital signature
			byte[] realSig = dsa.sign();
			// save the signature in a file
	        FileOutputStream sigfos = new FileOutputStream(outSignatureFileName);
	        sigfos.write(realSig);
	        sigfos.close();
	        // save the cert in a file
	        saveCerttoFileDer(outCertFileName, cert);

		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchProviderException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SignatureException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
    
    public boolean verifySignatureofFile(String inDataFileName, Certificate cert, 
    		String inSignatureFileName) {
    	boolean verifies = false;
    	
		try {
	        PublicKey pubKey = cert.getPublicKey();
	        // Read signature
	        FileInputStream sigfis = new FileInputStream(inSignatureFileName);
	        byte[] sigToVerify = new byte[sigfis.available()]; 
	        sigfis.read(sigToVerify);
	        sigfis.close();
	        // Init signature object for verification
	        Signature sig = Signature.getInstance("SHA1withRSA", "BC");
	        sig.initVerify(pubKey);
	        // Supply data to be verified
	        FileInputStream datafis = new FileInputStream(inDataFileName);
	        BufferedInputStream bufin = new BufferedInputStream(datafis);
	        byte[] buffer = new byte[1024];
	        int len;
	        while (bufin.available() != 0) {
	            len = bufin.read(buffer);
	            sig.update(buffer, 0, len);
	        };
	        bufin.close();
	        verifies = sig.verify(sigToVerify);
	        
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchProviderException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SignatureException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return verifies;

    }
    
    public static void main(String[] args) throws Exception {
    	
    	// User defined keystore file
    	// KeyStoreManager ksm = new KeyStoreManager("/home/ebayer/keystore.ks", "keystorepassword", "RSA");
    	KeyStoreManager ksm = new KeyStoreManager("/home/ebayer/keystore.ks", "keystorepassword");
 
        if (ksm.keyStore == null) {
        	System.out.println("Keystore file not found. Creating one.");
        	ksm.createKeyStore("/home/ebayer/keystore.ks", "keystorepassword");
        }
        
//        System.out.println("Key aliases in keystore");
//        System.out.println(ksm.listAllKeys().toString());
//        
//        System.out.println("Cert aliases in keystore");
//        System.out.println(ksm.listAllCerts().toString());
        
//        KeyPair key = ksm.createKeyPair("RSA", 1024);
        
//        ksm.saveKeyPair("Test2", key, "12345");
        
//        X509Certificate chain = ksm.generateCertificate(key.getPublic(), key.getPrivate(), 
//        		BigInteger.valueOf(1), "C=AU, O=BC, OU=BC Primary Certificate", 
//        		new Date( System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30), 
//        		new Date( System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30), 
//        		"C=AU, O=BC, OU=BC Primary Certificate", "MD5WithRSAEncryption");
//        ksm.saveCertificate("TestCert2", chain);

//        SecretKey secretKey = ksm.createSecretKey("Blowfish", 256);
//        ksm.saveSecretKey("SecretKey", secretKey, "12345");
        
//        ksm.loadKeyPairfromFile("/home/ebayer/certs/test2.key", "/home/ebayer/certs/test2.crt", "loaded2", "12345");
//        ksm.saveKeyStore();
        
//        ksm.deleteKeyPair("secretkey");
//        ksm.saveKeyStore();
        
//        ksm.deleteCert("testcert2");
//        ksm.saveKeyStore();
        
        PEMReader inp = new PEMReader(new FileReader("/home/ebayer/certs/export.crt"));
        X509Certificate cert = (X509Certificate) inp.readObject();
        ksm.saveCertificate("export", cert);
//        ksm.deleteCert("export");
        ksm.saveKeyStore();
        
        System.out.println("Key aliases in keystore");
        System.out.println(ksm.listAllKeys().toString());
        
        HashSet<String> keys = ksm.listAllKeys();
        for (String k : keys) {
        	System.out.println("******" + k + "*********");
        	if (ksm.getPublicKey(k) == null) {
        		// No certificate entry so it must be secretKey
        		System.out.println("Secret key");
            	System.out.println(ksm.getPrivateKey(k, "12345").toString());
            	System.out.println();
//            	System.out.println("Saving secretkey to file.\n");
//            	ksm.saveKeytoFile("/home/ebayer/certs/" + k + ".secretkey", ksm.getPrivateKey(k, "12345"));
//            	System.out.println();
        	} else {
        	if (!ksm.getPublicKey(k).equals(null)) {
        		System.out.println("Public key");
            	System.out.println(ksm.getPublicKey(k).toString());
            	System.out.println("Certificate without tostring()");
            	System.out.println("*****************--------------*******************");
            	System.out.println(ksm.keyStore.getCertificate(k));
            	System.out.println();
            	System.out.println("Saving cert to a file in PEM format");
//            	ksm.saveX509toFile("/home/ebayer/certs/" + k + ".crt", (X509Certificate) ksm.keyStore.getCertificate(k));
            	System.out.println();
        	}
        	if (!ksm.getPrivateKey(k, "12345").equals(null)) {
        		System.out.println("Private key");
        		System.out.println(ksm.getPrivateKey(k, "12345").toString());
        		System.out.println();
        		System.out.println("Saving private key to file.\n");
        		ksm.saveKeytoFile("/home/ebayer/certs/" + k + ".key", ksm.getPrivateKey(k, "12345"));
        		System.out.println();
        	}
        	}
		}
        
        System.out.println("Cert aliases in keystore");
        System.out.println(ksm.listAllCerts().toString());
        
        System.out.println();
        HashSet<String> certs = ksm.listAllCerts();
        for (String k : certs) {
        	System.out.println("******" + k + "*********");
        	if(!ksm.keyStore.getCertificate(k).equals(null)) {
        		System.out.println("Certificate");
        		System.out.println(ksm.keyStore.getCertificate(k).toString());
        		System.out.println();
        		System.out.println("Saving cert to a file in PEM format");
//            	ksm.saveX509toFile("/home/ebayer/certs/" + k + ".crt", (X509Certificate) ksm.keyStore.getCertificate(k));
            	System.out.println();
        	}
		}
        
        // Always save the keystore before you quit this class
        ksm.saveKeyStore();
        
        
    }
}